package com.ldr.custom.spring.v3.aop.intercept;

import com.ldr.custom.spring.v3.aop.GPJoinPoint;
import lombok.Data;

import java.lang.reflect.Method;
import java.util.List;
@Data
public class GPReflectiveMethodInvocation implements GPJoinPoint {

    private List<Object> interceptorsAndDynamicMethodMatchers;
    private Method method;
    private Object[] arguments;
    private Class<?> targetClass;
    private Object target;
    private Object proxy;

    //调用链索引，从-1开始来记录当前拦截器执行位置
    private int currentInterceptorIndex = -1;

    public GPReflectiveMethodInvocation(
            Object proxy, Object target, Method method, Object[] arguments,
            Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {

        this.proxy = proxy;
        this.target = target;
        this.targetClass = targetClass;
        this.method = method;
        this.arguments = arguments;
        this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
    }

    //执行调用链
    public Object proceed() throws Throwable {


        //如果Interceptor执行完了，则执行joinPoint
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return this.method.invoke(this.target, this.arguments);
        }

        Object interceptorOrInterceptionAdvice =
                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        //如果要动态匹配joinPoint
        if (interceptorOrInterceptionAdvice instanceof GPMethodInterceptor) {
            GPMethodInterceptor mi =
                    (GPMethodInterceptor) interceptorOrInterceptionAdvice;

            return mi.invoke(this);
        } else {
            //动态匹配失败时,略过当前Intercetpor,调用下一个Interceptor
            return proceed();
        }
    }

    @Override
    public Object getThis() {
        return this.target;
    }
}



